#pragma once
#include "Socket.hpp"
#include <iostream>
#include <pthread.h>
#include <functional>

using func_t = std::function<std::string(std::string &, bool *error_code)>;

class TcpServer;

class ThreadDate
{
public:
    ThreadDate(TcpServer *svr_this, Net_Work::Socket *socket)
        : _svr_this(svr_this), _socket(socket)
    {
    }

public:
    TcpServer *_svr_this;
    Net_Work::Socket *_socket;
};

class TcpServer
{
public:
    TcpServer(uint16_t port, func_t headler_request)
        : _port(port), _listensocket(new Net_Work::TcpSokcet), _headler_request(headler_request)
    {
        _listensocket->BUlidListenSockfdMethod(_port, Net_Work::default_backlog);
    }

    static void *ThreadRun(void *args)
    {
        pthread_detach(pthread_self());
        ThreadDate *td = static_cast<ThreadDate *>(args);
        std::string inbuffer;
        while (true)
        {
            bool ok = true;
            if (!td->_socket->Recv(&inbuffer, 4096))
                break;
            // 1. ok:处理请求中是否出错，如请求字段不符合要求格式等问题
            // 2. 报文不是完成的，下一次读取，返回空
            std::string send_result = td->_svr_this->_headler_request(inbuffer, &ok);
            if (ok)
            {
                if (!send_result.empty())
                    td->_socket->Send(send_result);
            }
            else
                break;
        }

        td->_socket->ColseSockfd();
        delete td->_socket;
        delete td;
        return nullptr;
    }

    void Loop()
    {
        while (true)
        {
            std::string clientip;
            uint16_t clientport;
            Net_Work::Socket *newsocket = _listensocket->AcceptSocket(&clientip, &clientport);
            if (newsocket != nullptr)
            {
                std::cout << "获得一个新连接， fd: " << newsocket->GetSockfd() << " client info: " << clientip << ":" << clientport << std::endl;
                ThreadDate *td = new ThreadDate(this, newsocket);
                pthread_t tid;
                pthread_create(&tid, nullptr, ThreadRun, td);
            }
        }
    }
    ~TcpServer()
    {
        // fd close ?
    }

private:
    Net_Work::Socket *_listensocket;
    uint16_t _port;

public:
    func_t _headler_request;
};